Trend Following System - Apple Stock

Calculate slow and fast exponential moving averages for AAPL stock using historical data, visualize results and calculate return and performance metrics. Our strategy purchases the stock as the fast exponential moving average crosses above the slow moving average. This system does not go short.

Alex Labuda (Suny New Paltz School of Business - Analytics Capstone) , Camila Campi , Deniz Ahman
9/9/2021

Retrieve Apple and S&P500 Historical Data

[1] "AAPL"
[1] "GSPC"
[1] "DAL"

Sample Period

Apple
[1] "Our sample considers OHLC data from 2008-01-29 through 2023-12-15 for Apple, Delta and the S&P500"
      Date                 Open             High       
 Min.   :2008-01-29   Min.   :  2.84   Min.   :  2.93  
 1st Qu.:2012-01-16   1st Qu.: 14.64   1st Qu.: 14.92  
 Median :2016-01-06   Median : 28.30   Median : 28.57  
 Mean   :2016-01-06   Mean   : 52.91   Mean   : 53.49  
 3rd Qu.:2019-12-26   3rd Qu.: 66.26   3rd Qu.: 67.00  
 Max.   :2023-12-15   Max.   :198.02   Max.   :199.62  
      Low             Close       
 Min.   :  2.79   Min.   :  2.79  
 1st Qu.: 14.58   1st Qu.: 14.71  
 Median : 28.00   Median : 28.29  
 Mean   : 52.36   Mean   : 52.95  
 3rd Qu.: 65.64   3rd Qu.: 66.52  
 Max.   :197.00   Max.   :198.11  
[1] 54.61935
SPX
summary(SPX[,1:5])
      Date                 Open             High       
 Min.   :2008-01-29   Min.   : 679.3   Min.   : 695.3  
 1st Qu.:2012-01-16   1st Qu.:1354.3   1st Qu.:1362.3  
 Median :2016-01-06   Median :2088.8   Median :2096.9  
 Mean   :2016-01-06   Mean   :2351.7   Mean   :2365.2  
 3rd Qu.:2019-12-26   3rd Qu.:3003.3   3rd Qu.:3014.7  
 Max.   :2023-12-15   Max.   :4804.5   Max.   :4818.6  
      Low             Close       
 Min.   : 666.8   Min.   : 676.5  
 1st Qu.:1343.3   1st Qu.:1354.6  
 Median :2079.2   Median :2088.7  
 Mean   :2337.1   Mean   :2352.1  
 3rd Qu.:2988.3   3rd Qu.:3003.4  
 Max.   :4780.0   Max.   :4796.6  
sd(SPX$Close)
[1] 1108.915
Delta
summary(dal_df[,1:5])
      Date                 Open            High            Low       
 Min.   :2008-01-29   Min.   : 3.90   Min.   : 4.06   Min.   : 3.51  
 1st Qu.:2012-01-16   1st Qu.:11.79   1st Qu.:12.04   1st Qu.:11.57  
 Median :2016-01-06   Median :36.03   Median :36.66   Median :35.35  
 Mean   :2016-01-06   Mean   :31.77   Mean   :32.24   Mean   :31.27  
 3rd Qu.:2019-12-26   3rd Qu.:46.89   3rd Qu.:47.43   3rd Qu.:46.20  
 Max.   :2023-12-15   Max.   :63.23   Max.   :63.44   Max.   :62.38  
     Close      
 Min.   : 3.93  
 1st Qu.:11.80  
 Median :36.03  
 Mean   :31.75  
 3rd Qu.:46.76  
 Max.   :63.16  
sd(dal_df$Close)
[1] 17.40375

Calculate Daily Return

Calculate a simple day-to-day return, from adjusted-close to adjusted-close and store in return and log_return vector:

        Date    Close       return   log_return
1 2008-01-29 4.697857           NA           NA
2 2008-01-30 4.720714  0.004865388  0.004853591
3 2008-01-31 4.834286  0.024058299  0.023773457
4 2008-02-01 4.776786 -0.011893802 -0.011965099
5 2008-02-04 4.701786 -0.015701285 -0.015825856
6 2008-02-05 4.620000 -0.017394305 -0.017547363
        Date Close       return   log_return
1 2008-01-29 16.01           NA           NA
2 2008-01-30 16.15  0.008744486  0.008706474
3 2008-01-31 16.82  0.041486058  0.040648595
4 2008-02-01 18.53  0.101664875  0.096822558
5 2008-02-04 17.25 -0.069077136 -0.071578858
6 2008-02-05 17.03 -0.012753773 -0.012835801
        Date   Close       return   log_return
1 2008-01-29 1362.30           NA           NA
2 2008-01-30 1355.81 -0.004763995 -0.004775379
3 2008-01-31 1378.55  0.016772254  0.016633153
4 2008-02-01 1395.42  0.012237492  0.012163219
5 2008-02-04 1380.82 -0.010462869 -0.010517990
6 2008-02-05 1336.64 -0.031995433 -0.032518473

Indicators and Studies

Simple Moving Averages Functions

Create a function to calculate two simple moving averages of differing lengths for use for a trend-following trading system (for this system we won’t be using a simple moving average):

Exponential Moving Averages Function

Create a function to calculate two exponential moving averages of differing lengths for use for a trend-following trading system and store in fast_ma, slow_ma and ema_diff vector:

           Date   Open   High    Low  Close    Volume  Price
3995 2023-12-08 194.20 195.99 193.67 195.71  53377300 195.71
3996 2023-12-11 193.11 193.49 191.42 193.18  60943700 193.18
3997 2023-12-12 193.08 194.72 191.72 194.71  52696900 194.71
3998 2023-12-13 195.09 198.00 194.85 197.96  70404200 197.96
3999 2023-12-14 198.02 199.62 196.16 198.11  66831600 198.11
4000 2023-12-15 197.53 198.40 197.00 197.57 128256700 197.57
           return    log_return  slow_ma  fast_ma   ema_diff
3995  0.007412377  0.0073850400 178.4263 188.2086  -9.782240
3996 -0.012927362 -0.0130116472 178.6217 188.5910  -9.969244
3997  0.007920148  0.0078889478 178.8348 189.0617 -10.226848
3998  0.016691489  0.0165537174 179.0881 189.7462 -10.658021
3999  0.000757698  0.0007574111 179.3401 190.3895 -11.049447
4000 -0.002725725 -0.0027294461 179.5816 190.9419 -11.360335
           Date  Open  High   Low Close   Volume Price        return
3995 2023-12-08 40.26 40.74 39.86 40.35  8723000 40.35  0.0002478513
3996 2023-12-11 40.41 40.63 40.11 40.51  7295400 40.51  0.0039653000
3997 2023-12-12 40.52 41.46 40.52 41.24  8448900 41.24  0.0180203255
3998 2023-12-13 40.87 41.36 40.12 41.19 12821300 41.19 -0.0012124891
3999 2023-12-14 41.53 42.70 41.49 42.44 14530800 42.44  0.0303471727
4000 2023-12-15 42.59 42.59 41.98 42.34 12902100 42.34 -0.0023562318
        log_return  slow_ma  fast_ma    ema_diff
3995  0.0002478206 37.69339 36.66494  1.02844868
3996  0.0039574589 37.73070 36.96072  0.76998124
3997  0.0178598841 37.77718 37.28989  0.48728631
3998 -0.0012132247 37.82238 37.58990  0.23248104
3999  0.0298958063 37.88354 37.96298 -0.07944294
4000 -0.0023590121 37.94257 38.29968 -0.35711049

Average True Range

True Range

First calculate the maximum of the aforementioned ranges and store in max_range vector:

         Date     Open     High      Low    Close max_range
25 2008-03-04 4.356786 4.460000 4.300000 4.450714 0.1599998
26 2008-03-05 4.413571 4.469286 4.366071 4.446071 0.1032147
27 2008-03-06 4.450357 4.553571 4.314643 4.318929 0.2389283
28 2008-03-07 4.300357 4.392143 4.251786 4.366071 0.1403565
29 2008-03-10 4.356429 4.409286 4.263214 4.274643 0.1460719
30 2008-03-11 4.432143 4.552857 4.357143 4.548214 0.2782140
31 2008-03-12 4.537143 4.595714 4.470357 4.501071 0.1253572
32 2008-03-13 4.432143 4.625000 4.392857 4.569286 0.2321429
         Date  Open  High   Low Close max_range
25 2008-03-04 12.85 13.53 12.51 13.14  1.020000
26 2008-03-05 13.19 14.60 12.87 14.33  1.730000
27 2008-03-06 14.15 14.45 13.34 13.50  1.110000
28 2008-03-07 13.13 13.75 12.71 12.89  1.040000
29 2008-03-10 12.92 13.26 11.95 11.98  1.310000
30 2008-03-11 12.16 12.64 11.64 12.11  1.000000
31 2008-03-12 11.58 11.80 10.05 10.13  2.059999
32 2008-03-13  9.82 10.72  9.56 10.52  1.160000

Average True Range Function

Create function that uses the true range vector to calculate a moving average of the true range with a user-specified lag period and store in atr vector:

Risk per lot

This is a multiple of the ATR for volatility-based position sizing:

Store in risk_per_lot vector:

       Close max_range       atr risk_per_lot
200 3.424286 0.2107141 0.2431697    1.2158484
201 3.384643 0.1753569 0.2398661    1.1993305
202 3.218571 0.1700001 0.2342411    1.1712056
203 3.444286 0.3721430 0.2357144    1.1785718
204 3.222857 0.2300000 0.2336831    1.1684156
205 3.147857 0.1174998 0.2229019    1.1145093
206 3.211071 0.1475000 0.2192411    1.0962056
207 3.081786 0.1917851 0.2124554    1.0622769
208 2.874643 0.2303572 0.2053571    1.0267857
209 2.949286 0.1778572 0.1994196    0.9970982
210 3.319643 0.4360709 0.2135045    1.0675223
    Close max_range      atr risk_per_lot
200  8.98 0.8299999 1.316250     6.581250
201  8.84 0.6099997 1.303125     6.515625
202  7.37 1.7300000 1.349375     6.746875
203  8.17 0.9800000 1.281875     6.409376
204  7.85 0.6999998 1.232500     6.162500
205  7.87 0.7000003 1.178125     5.890626
206  7.88 0.8799996 1.150000     5.750000
207  7.00 1.0400004 1.138750     5.693751
208  7.02 1.1199999 1.163750     5.818750
209  6.82 1.1900001 1.140625     5.703125
210  7.35 0.9099998 1.041250     5.206250
           Date       Open       High        Low      Close
161  2008-09-16   4.780714   5.089286   4.719643   4.995714
1208 2012-11-12  19.791071  19.803572  19.237499  19.386786
1897 2015-08-10  29.132500  29.997499  29.132500  29.930000
2071 2016-04-19  26.969999  27.000000  26.557501  26.727501
2726 2018-11-21  44.932499  45.067501  44.137501  44.195000
2857 2019-06-04  43.860001  44.957500  43.630001  44.910000
3063 2020-03-27  63.187500  63.967499  61.762501  61.935001
3598 2022-05-11 153.500000 155.449997 145.809998 146.500000
3693 2022-09-27 152.740005 154.720001 149.949997 151.759995
3967 2023-10-30 169.020004 171.169998 168.869995 170.289993
         Volume      Price       return   log_return    slow_ma
161  1199836400   4.234766 -0.003419992 -0.003425854   5.747746
1208  515802000  16.579723 -0.007732394 -0.007762444  21.457792
1897  219806400  27.131920  0.036357241  0.035711912  30.521466
2071  129539600  24.464569 -0.005303042 -0.005317153  26.907706
2726  124496800  42.418835 -0.001130391 -0.001131031  50.357920
2857  123872000  43.456688  0.036584101  0.035930789  46.671909
3063  204216800  60.482262 -0.041402368 -0.042283863  66.466317
3598  142689800 145.242661 -0.051841303 -0.053233389 161.335502
3693   84442700 150.666504  0.006566175  0.006544712 156.180428
3967   51131000 170.065933  0.012305221  0.012230127 174.363520
        fast_ma     ema_diff max_range       atr risk_per_lot
161    5.722272 0.0254730475 0.3696427 0.2368751     1.184375
1208  21.451680 0.0061117641 0.5660725 0.6715622     3.357811
1897  30.497427 0.0240385186 1.1175003 0.7928125     3.964062
2071  26.907096 0.0006101968 0.4424992 0.5092187     2.546093
2726  50.248957 0.1089631330 0.9300003 1.8137500     9.068750
2857  46.601018 0.0708910523 1.6324997 1.3182809     6.591405
3063  66.384702 0.0816144377 2.8474998 4.9378126    24.689063
3598 160.683833 0.6516691677 9.6399994 6.2474985    31.237493
3693 156.138959 0.0414687757 4.7700043 4.6318750    23.159375
3967 174.234966 0.1285538854 2.9499969 3.0418768    15.209384
           Date       Open       High        Low      Close
40   2008-03-26   5.031071   5.205000   5.022857   5.180714
304  2009-04-13   4.286071   4.320714   4.250000   4.293571
1399 2013-08-16  17.862499  17.962143  17.816429  17.940357
2069 2016-04-15  28.027500  28.075001  27.432501  27.462500
2148 2016-08-08  26.879999  27.092501  26.790001  27.092501
2809 2019-03-26  47.915001  48.220001  46.145000  46.697498
2861 2019-06-10  47.952499  48.842499  47.904999  48.145000
3076 2020-04-16  71.845001  72.050003  70.587502  71.672501
3656 2022-08-04 166.009995 167.190002 164.429993 165.809998
3790 2023-02-15 153.110001 155.500000 152.880005 155.330002
3971 2023-11-03 174.240005 176.820007 173.350006 176.649994
         Volume      Price       return   log_return    slow_ma
40   1182084400   4.391586  0.028939792  0.028528944   4.638723
304   389236400   3.639573  0.005436167  0.005421445   3.826802
1399  362306000  15.636866  0.008877278  0.008838106  16.415864
2069  187756000  25.137335 -0.020071386 -0.020275553  26.910664
2148  112148800  25.084808  0.008280810  0.008246712  25.439263
2809  199202000  45.012997 -0.010331732 -0.010385475  45.161955
2861  104883600  46.587002  0.012779386  0.012698419  46.684806
3076  157125200  69.991356  0.007945646  0.007914245  66.394240
3656   55474100 164.386948 -0.001926153 -0.001928010 153.529224
3790   65573800 154.702454  0.013903423  0.013807657 146.176338
3971   79763700 176.417572 -0.005181159 -0.005194628 174.384907
        fast_ma      ema_diff max_range       atr risk_per_lot
40     4.641450 -0.0027265677 0.1821427 0.1907812    0.9539059
304    3.838849 -0.0120475123 0.0707140 0.1428793    0.7143966
1399  16.450733 -0.0348689245 0.1796436 0.3495760    1.7478800
2069  26.926401 -0.0157370506 0.6424999 0.4750001    2.3750007
2148  25.440247 -0.0009847918 0.3024998 0.4473438    2.2367191
2809  45.256133 -0.0941787961 2.0750008 1.0417192    5.2085960
2861  46.708433 -0.0236272637 1.3050003 1.2028127    6.0140634
3076  66.711820 -0.3175799840 1.4625015 2.6524994   13.2624972
3656 153.556168 -0.0269442059 2.7600098 3.9068747   19.5343733
3790 146.585439 -0.4091013714 2.6199951 3.9224977   19.6124887
3971 174.430541 -0.0456339127 4.2200012 3.3275013   16.6375065
           Date  Open  High   Low Close   Volume     Price
24   2008-03-03 13.27 13.35 12.50 12.98  4713200 11.473168
204  2008-11-14  8.09  8.46  7.76  7.85  8104200  6.938703
258  2009-02-04  7.00  7.12  6.50  6.51 11712200  5.754263
624  2010-07-20 11.18 11.62 11.10 11.53  9408900 10.191496
753  2011-01-21 11.71 11.78 11.39 11.54 15559900 10.200332
1138 2012-08-01  9.49  9.62  9.40  9.48 15043400  8.379476
1690 2014-10-13 33.30 33.31 30.12 30.90 41248000 27.618723
1853 2015-06-08 42.37 42.62 40.65 40.75 18359700 36.649052
2015 2016-01-28 44.84 45.00 42.52 43.20 13996900 39.069401
2074 2016-04-22 43.43 44.67 43.16 44.62 14258600 40.481609
2318 2017-04-11 45.00 45.32 44.49 45.29 10506800 41.805256
2413 2017-08-25 45.43 47.06 45.35 46.68 13938800 43.545124
2589 2018-05-09 52.17 52.28 51.46 51.62  8403900 48.732544
2623 2018-06-27 51.03 51.18 49.70 49.89  9035800 47.379253
2702 2018-10-18 54.29 54.30 52.96 53.13  5871200 50.800251
2746 2018-12-21 50.51 51.28 49.29 49.45 11680200 47.578716
2946 2019-10-09 54.01 54.40 53.59 53.92  7615300 52.895599
2986 2019-12-05 56.39 56.41 55.70 55.88  3899900 55.225609
3041 2020-02-26 51.44 51.77 49.00 49.59 15985900 49.347950
3391 2021-07-16 41.83 42.05 39.84 40.06 16726600 39.864468
3456 2021-10-18 40.67 41.41 40.52 41.01 10140200 40.809826
3550 2022-03-03 38.49 38.74 36.38 36.56 17589100 36.381550
3607 2022-05-24 38.82 38.95 36.78 37.22 10856500 37.038326
3615 2022-06-06 39.00 39.29 38.31 39.00 12330400 38.809635
3752 2022-12-20 32.86 33.28 32.75 32.90  5995900 32.739414
3816 2023-03-24 31.74 31.86 31.04 31.59 12647300 31.435808
3944 2023-09-27 36.77 37.15 36.53 36.66  7996900 36.557686
            return    log_return   slow_ma   fast_ma    ema_diff
24   -0.0277152131 -0.0281065268 16.137392 15.942950 0.194442154
204  -0.0391677668 -0.0399554605  8.792714  8.790646 0.002067308
258  -0.0565213244 -0.0581815158  9.314662  9.281247 0.033415222
624   0.0131809034  0.0130947911 12.138142 12.121677 0.016464694
753  -0.0060293459 -0.0060475958 12.441692 12.429321 0.012371028
1138 -0.0176167864 -0.0177738089 10.136524 10.119460 0.017063860
1690 -0.0610759260 -0.0630206614 36.256417 36.147118 0.109298469
1853 -0.0501164796 -0.0514159120 43.967611 43.864808 0.102802775
2015 -0.0339892714 -0.0345803387 47.192733 46.987755 0.204978627
2074 -0.0077830791 -0.0078135253 47.098074 47.017579 0.080495053
2318  0.0071159808  0.0070907816 46.402673 46.363002 0.039671307
2413  0.0325149562  0.0319975312 49.272102 49.117258 0.154844325
2589 -0.0143211471 -0.0144246844 53.213014 53.148667 0.064346206
2623 -0.0231056420 -0.0233767617 53.365226 53.318601 0.046625021
2702 -0.0215467225 -0.0217822424 54.346382 54.271469 0.074913582
2746 -0.0286779847 -0.0290972330 54.838522 54.693107 0.145415298
2946  0.0135338473  0.0134430828 56.682551 56.506699 0.175852033
2986 -0.0032108907 -0.0032160566 56.330176 56.322690 0.007486750
3041 -0.0255452344 -0.0258771791 57.180516 56.932703 0.247812371
3391 -0.0311969922 -0.0316939821 43.547324 43.329234 0.218090202
3456  0.0004878033  0.0004876843 42.211823 42.203141 0.008681967
3550 -0.0389063741 -0.0396834493 40.603786 40.411866 0.191920582
3607 -0.0581984495 -0.0599606948 39.856313 39.740031 0.116281668
3615  0.0119355868  0.0118649194 39.874651 39.841234 0.033417579
3752 -0.0006073834 -0.0006075679 33.944100 33.929391 0.014709243
3816 -0.0171126373 -0.0172607507 35.623545 35.506664 0.116881284
3944 -0.0029915316 -0.0029960152 40.151455 39.992967 0.158487997
     max_range       atr risk_per_lot
24   0.8500004 0.9524999     4.762499
204  0.6999998 1.2325001     6.162500
258  0.6199999 1.1000001     5.500000
624  0.5199995 0.6918748     3.459374
753  0.3899994 0.4356251     2.178125
1138 0.2500000 0.4187499     2.093750
1690 3.1900005 1.4331254     7.165627
1853 2.2500000 1.4418755     7.209377
2015 2.4799995 2.0868747    10.434374
2074 1.8100014 1.3693745     6.846873
2318 0.8299980 0.9218750     4.609375
2413 1.8500023 1.0218759     5.109379
2589 0.9099998 1.2231250     6.115625
2623 1.4799995 1.2256248     6.128124
2702 1.3400002 1.4993751     7.496876
2746 1.9899979 1.8862500     9.431250
2946 1.2000008 1.3774996     6.887498
2986 0.7099991 0.9981256     4.990628
3041 2.7700005 1.7006252     8.503126
3391 2.2099991 1.3481250     6.740625
3456 0.8899994 1.3131254     6.565627
3550 2.3600006 1.9406245     9.703122
3607 2.7400017 1.9162505     9.581252
3615 0.9799995 1.8456254     9.228127
3752 0.5299988 1.1831257     5.915629
3816 1.0999985 1.3850003     6.925002
3944 0.6200027 0.9112499     4.556249
           Date  Open  High   Low Close   Volume     Price
196  2008-11-04 11.08 12.00 10.03 11.28 24872000  9.970517
220  2008-12-09 10.78 11.64 10.53 10.87 18926300  9.608114
400  2009-08-27  7.48  7.50  7.25  7.49 10430300  6.620494
690  2010-10-21 13.03 13.54 12.90 13.53 20095600 11.959317
1004 2012-01-20  9.30  9.50  9.25  9.41  7844600  8.317603
1195 2012-10-22 10.00 10.20  9.90 10.14  7317200  8.962858
1700 2014-10-27 39.38 40.10 39.20 39.75 18958800 35.528942
1889 2015-07-29 44.81 45.33 43.85 44.18 10355300 39.733864
2039 2016-03-03 48.59 49.01 48.35 48.79  8853700 44.264851
2210 2016-11-03 42.06 42.57 41.77 41.92  8142800 38.364189
2334 2017-05-04 48.46 48.80 48.20 48.64  7467400 44.897484
2442 2017-10-06 51.40 52.52 51.40 52.01  6735400 48.517178
2600 2018-05-24 53.53 54.57 53.53 54.40  5251200 51.662292
2651 2018-08-07 54.60 55.09 54.52 54.70  4425300 52.301403
2714 2018-11-05 56.02 56.38 55.55 56.05  5206000 53.592209
2817 2019-04-05 57.44 58.20 57.33 57.73  6918300 55.933578
2981 2019-11-27 57.53 57.58 56.68 57.07  4062500 56.401676
2993 2019-12-16 57.17 58.49 57.15 58.42  7460700 57.735863
3223 2020-11-12 34.09 35.55 34.02 34.38 21676300 34.212189
3447 2021-10-05 44.99 45.56 44.46 44.74  9596000 44.521622
3538 2022-02-14 42.38 43.25 41.71 41.97 11581600 41.765141
3584 2022-04-21 44.81 46.27 44.54 44.73 31849600 44.511669
3610 2022-05-27 41.00 42.23 41.00 42.23 10730600 42.023872
3738 2022-11-30 34.51 35.38 34.21 35.37  7404100 35.197357
3764 2023-01-09 36.54 37.42 36.35 36.77 11251300 36.590527
3863 2023-06-01 36.42 36.81 36.00 36.38  7769000 36.202427
3999 2023-12-14 41.53 42.70 41.49 42.44 14530800 42.439999
            return    log_return   slow_ma   fast_ma     ema_diff
196  -0.0208331948 -0.0210532677  8.791047  8.890360 -0.099312565
220  -0.0136117888 -0.0137052785  8.747561  8.871540 -0.123978743
400   0.0040213838  0.0040133197  6.900195  6.930079 -0.029884534
690   0.0431765733  0.0422704554 11.713393 11.730301 -0.016907856
1004  0.0085746269  0.0085380735  8.547007  8.562098 -0.015091284
1195  0.0139998129  0.0139027207  9.778188  9.798855 -0.020667766
1700  0.0078599166  0.0078291883 36.246599 36.426752 -0.180152894
1889 -0.0162549420 -0.0163885029 43.440206 43.444856 -0.004649746
2039  0.0049430620  0.0049308852 46.839241 46.900670 -0.061428635
2210 -0.0002385842 -0.0002386127 40.537933 40.600753 -0.062820548
2334  0.0068308532  0.0068076286 46.334027 46.377038 -0.043010701
2442  0.0063855320  0.0063652309 49.020699 49.140316 -0.119616838
2600  0.0187264791  0.0185532973 53.202877 53.215520 -0.012642347
2651  0.0051452620  0.0051320704 52.954865 52.959755 -0.004889844
2714 -0.0012472257 -0.0012480041 54.339901 54.442930 -0.103028884
2817  0.0089128831  0.0088733978 52.148067 52.183860 -0.035793478
2981 -0.0067872694 -0.0068104076 56.331252 56.349205 -0.017952896
2993  0.0297902162  0.0293551079 56.332870 56.381922 -0.049052243
3223 -0.0182752442 -0.0184442993 32.438902 32.526346 -0.087443534
3447 -0.0048932230 -0.0049052340 42.186628 42.191977 -0.005349117
3538 -0.0085046783 -0.0085410494 40.566451 40.641506 -0.075054663
3584  0.0273311264  0.0269643000 39.631573 39.784479 -0.152905831
3610  0.0342884901  0.0337137412 39.884276 39.934239 -0.049963328
3738  0.0219589725  0.0217213466 33.897592 33.929432 -0.031840072
3764  0.0205385795  0.0203305071 33.925796 34.025409 -0.099612477
3863  0.0013762495  0.0013753033 35.093709 35.099561 -0.005852164
3999  0.0303471727  0.0298958063 37.883542 37.962985 -0.079442944
     max_range       atr risk_per_lot
196  1.9700003 1.3193751     6.596875
220  1.1100006 1.0050000     5.025000
400  0.2500000 0.3500000     1.750000
690  0.6400003 0.4850000     2.425000
1004 0.2500000 0.3181249     1.590625
1195 0.3000002 0.3274999     1.637499
1700 0.8999977 1.8275003     9.137502
1889 1.4800034 1.2612500     6.306250
2039 0.6599998 1.2812495     6.406248
2210 0.7999992 1.1793752     5.896876
2334 0.5999985 1.0999992     5.499996
2442 1.1199989 1.0718753     5.359377
2600 1.1699982 1.0900004     5.450002
2651 0.6700020 1.1387506     5.693753
2714 0.8300018 1.6181254     8.090627
2817 0.9799995 1.2262497     6.131248
2981 0.9000015 0.8443754     4.221877
2993 1.7600021 1.0968750     5.484375
3223 1.5299988 1.9068747     9.534373
3447 1.1000023 1.3125007     6.562504
3538 1.5400009 1.6268749     8.134375
3584 2.7299995 1.4668751     7.334375
3610 1.3999977 1.9500005     9.750003
3738 1.1700020 1.0193758     5.096879
3764 1.3899994 1.0831250     5.415625
3863 0.8100014 1.0481250     5.240625
3999 1.5100021 1.0112507     5.056254

Candlestick Chart

Visualizing the Trend-following System for AAPL

Visualizing the Trend-following System for DAL

Generate signals using MA Indicator

Apple Stock

Now we use our indicator to generate trading signals and store them in signal vector:

          Date    Close  slow_ma  fast_ma signal
200 2008-11-10 3.424286 4.944619 3.739298      H
201 2008-11-11 3.384643 4.923957 3.712016      H
202 2008-11-12 3.218571 4.901369 3.674059      H
203 2008-11-13 3.444286 4.882070 3.656384      H
204 2008-11-14 3.222857 4.860094 3.623036      H
205 2008-11-17 3.147857 4.837415 3.586484      H
206 2008-11-18 3.211071 4.815874 3.557606      H
207 2008-11-19 3.081786 4.792906 3.521004      H
208 2008-11-20 2.874643 4.767498 3.471284      H
209 2008-11-21 2.949286 4.743416 3.431130      H
210 2008-11-24 3.319643 4.724558 3.422555      H

DAL Stock

          Date Close  slow_ma  fast_ma signal
200 2008-11-10  8.98 8.833187 9.075149      H
201 2008-11-11  8.84 8.833277 9.057060      H
202 2008-11-12  7.37 8.813896 8.927286      H
203 2008-11-13  8.17 8.805368 8.869034      H
204 2008-11-14  7.85 8.792714 8.790646      H
205 2008-11-17  7.87 8.780492 8.719828      S
206 2008-11-18  7.88 8.768565 8.655225      H
207 2008-11-19  7.00 8.745141 8.527900      H
208 2008-11-20  7.02 8.722291 8.411908      H
209 2008-11-21  6.82 8.697095 8.289454      H
210 2008-11-24  7.35 8.679253 8.217188      H

Holding Status and Investment Return

APPLE Stock

After generating the signals, we must calculate the return from our strategy:

Store in investment_return vector

DAL Stock

Cumulative Return

Apple Stock

From the individual daily returns, we must create a cash and number of stocks vector to hold each days current figures.

Calculate and store in cash and n_stock vector:

DAL Stock

Final Return

Apple Stock

Calculate the cash plus the value of the stock on hand for the last day in the sample.

Print final return from trend following system and buy-and-hold strategy:

[1] "Initial Investment: $ 100000.00"
[1] "Trend-following system Final Return: $ 3017008.55"
[1] "Buy and hold system Final Return: $ 4117924.89"

Delta Airlines Stock

[1] "Initial Investment: $ 100000.00"
[1] "Trend-following system Final Return: $ 70067.89"
[1] "Buy and hold system Final Return: $ 162001.84"

Visualize Days with Largest Loss and Gain

           Date    Open  High Low   Close    Volume    Price
3054 2020-03-16 60.4875 64.77  60 60.5525 322423600 59.13219
        return log_return  slow_ma  fast_ma  ema_diff max_range
3054 -0.128647 -0.1377081 67.15978 71.94174 -4.781956    9.4925
          atr risk_per_lot MACD_direction signal holding Inv_return
3054 5.212188     26.06094     Decreasing      H       1  -0.128647
         cash n_stock
3054 16.21134   22389
           Date    Open  High     Low   Close    Volume   Price
3053 2020-03-13 66.2225 69.98 63.2375 69.4925 370732000 67.8625
        return log_return  slow_ma  fast_ma ema_diff max_range
3053 0.1198084  0.1131576 67.24847 72.89084 -5.64237  7.922504
          atr risk_per_lot MACD_direction signal holding Inv_return
3053 4.774375     23.87188     Decreasing      H       1  0.1198083
         cash n_stock
3053 16.21134   22389

Largest Gain

Largest Loss

Max Adverse & Favorable Single-Day Returns

[1] "Largest 1-day return with trend system: 11.9808 %"
[1] "Largest 1-day loss with trend system: -12.8647 %"
[1] "Average 1-day with trend system return: 0.0995 %"
[1] "Largest 1-day return buy and hold strategy: 13.9049 %"
[1] "Largest 1-day loss with buy and hold strategy: -17.9195 %"
[1] "Average 1-day with buy and hold strategy: 0.1169 %"

Performance Evaluation

Distribution of Returns

Apple Stock

Create a histogram of returns for a simple buy and hold strategy, as well as for our trend-following system:

Delta Airlines Stock

Mean and Standard Deviation

AAPL

Retrieve the average daily return and volatility of our trend-following system, as well as a simple buy and hold strategy:

[1] "Average return: 0.000995"
[1] "Volatility: 0.014908"
[1] "Average return buy hold system: 0.001169"
[1] "Volatility buy hold system: 0.019597"
[1] "Buy and hold strategy experiences larger volatility for a small amount of additional return"

DAL

[1] "DAL Average return: -5.8e-05"
[1] "DAL Volatility: 0.018017"
[1] "As we can see, the average return when using this system for DAL is much smaller and the volatility is larger. We can expect the Sharpe ratio to be much smaller in this environment"

Sharpe Ratio

Apple Stock

The Sharpe ratio was developed by Nobel laureate William F. Sharpe and is used to help investors understand the return of an investment compared to its risk.12 The ratio is the average return earned in excess of the risk-free rate per unit of volatility or total risk. Volatility is a measure of the price fluctuations of an asset or portfolio.

[1] "AAPL Trend following: Sharpe ratio of daily returns: 0.066"
[1] "AAPL Buy & hold: Sharpe ratio of daily returns: 0.059"
[1] "Our AAPL Trend-following system achieves a slightly higher Sharpe ratio"

Delta Stock

[1] "DAL Trend following: Sharpe ratio of daily returns: -0.00377"
[1] "Compared to Apple Trend-following returns, DAL's example provides a much smaller Sharpe ratio - this is due to whipsaw-like nature of Delta's historical stock price and the trend-following's lack of ability to trade in this type of environment (at least with the parameters we have chosen)"

Value at Risk

Apple Stock

VAR measures the cut-off return that your financial asset will fall below with certain probability.

Value at risk (VaR) is a statistic that quantifies the extent of possible financial losses within a firm, portfolio, or position over a specific time frame. This metric is most commonly used by investmentand commercial banks to determine the extent and probabilities of potential losses in their institutional portfolios.

[1] "Apple Trend-following VAR: we can expect 95% of the time returns will be greater than: -2.3029"
[1] "Apple Buy / Hold model VAR: we can expect 95% of the time returns will be greater than: -2.8991"

Delta Airlines

[1] "DAL Trend-following VAR: we can expect 95% of the time returns will be greater than: -2.901"

Summary of Investment & Market Return

In order to break down risk into two components, we need to collect what part of the return was attributed to the market and what part to our trading system.

Fit CAPM Model


Call:
lm(formula = y ~ x)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.084280 -0.006368 -0.000612  0.006285  0.099440 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 0.0007526  0.0002058   3.656 0.000259 ***
x           0.5856195  0.0159334  36.754  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.01285 on 3899 degrees of freedom
  (99 observations deleted due to missingness)
Multiple R-squared:  0.2573,    Adjusted R-squared:  0.2571 
F-statistic:  1351 on 1 and 3899 DF,  p-value: < 2.2e-16
[1] "Trend-following system Beta: 0.5856"

The larger the \(BETA\) is, the larger the systematic risk is.

We use this to measure the aggressiveness of the stock or the trading system.

Our trend-following system is mostly conservative.

Jensen’s Alpha (Abnormal Return)

[1] "Jensen's Alpha: 8e-04"

Treynor’s Ratio

[1] "Treynor's Ratio Version 1: 0.0013"
[1] "Treynor's Ratio Version 2: 0.0017"

Historical Portfolio Return

raw_data$portfolio_value = raw_data$n_stock*raw_data$Close + raw_data$cash
# Plot main data
fig <- raw_data %>% plot_ly(x = ~Date, type="ohlc",
          open = ~Open, close = ~Close,
          high = ~High, low = ~Low, name = "AAPL",
          increasing = i, decreasing = d)

# Add Fast and Slow moving average lines
fig <- fig %>% add_lines(x = ~Date, y = ~slow_ma, name = "Slow EMA",
            line = list(color = '#ccc', width = 0.75),
            legendgroup = "Bands", inherit = F,
            showlegend = TRUE, hoverinfo = "none") 
fig <- fig %>% add_lines(x = ~Date, y = ~fast_ma, name = "Fast EMA",
            line = list(color = '#E377C2', width = 0.75),
            legendgroup = "bands",
            hoverinfo = "none", inherit = F)

ay <- list(
  tickfont = list(color = "grey"),
  overlaying = "y",
  side = "right",
  title = "<b>Secondary:</b> Portfolio Value")

fig <- fig %>% add_lines(x = ~Date, y = ~portfolio_value, name = "Portfolio Value",
            line = list(color =  'limegreen', width = 1), dash = 'dot', yaxis = "y2")

# Add y-axis title
fig <- fig %>% layout(yaxis = list(title = "Price"))


# Add arrow annotations
fig <- fig %>% layout(annotations = h_a)
fig <- fig %>% layout(annotations = l_a)



# Add title
fig <- fig %>% layout(
  title = "<b>Trend-Following System:</b> Portfolio Value", yaxis2 = ay,
  xaxis = list(rangeslider = list(visible = F)),
  yaxis = list(title = "<b>Primary:</b> Stock Price")
  ) %>%
  layout(plot_bgcolor = 'rgb(255, 255, 255)',
         xaxis = list(
            zerolinecolor = '#ffffff',
            zerolinewidth = 2,
            gridcolor = '#ffffff'),
          yaxis = list(
            zerolinecolor = '#ffffff',
            zerolinewidth = 2,
            gridcolor = '#ffffff')
          )


fig